package mask

import (
	"fmt"
	"os"

	"minio.com/minio-sdk/erasure"
	"minio.com/minio-sdk/util"
)

func GenMasks(k int, m int, m_len int) [][]byte {
	if k <= m {
		return nil
	}
	chunks := make([][]byte, k+m)
	for i := 0; i < m; i++ {
		chunks[i] = make([]byte, m_len)
	}
	for i := m; i < k; i++ {
		chunks[i] = util.RandData(m_len)
	}
	for i := k; i < k+m; i++ {
		chunks[i] = make([]byte, m_len)
	}
	var exists []int
	for i := 0; i < k; i++ {
		exists = append(exists, m+i)
	}
	if err := erasure.ErasureReconst(k, m, chunks, exists); err != nil {
		fmt.Println(err)
		return nil
	}
	var masks [][]byte
	for i := 0; i < k; i++ {
		masks = append(masks, chunks[i])
	}
	return masks
}

func XorDataWithMask(data []byte, mask []byte) error {
	data_len := len(data)
	mask_len := len(mask)

	if data_len%mask_len != 0 {
		return fmt.Errorf("the length of the data is not equal to mask")
	}
	for i := 0; i < data_len; i += mask_len {
		for j := 0; j < mask_len; j++ {
			data[i+j] ^= mask[j]
		}
	}
	return nil
}

func LoadMask(ORG_ID string) ([]byte, error) {
	maskFilePath := "./mask/mask" + ORG_ID
	maskFile, err := os.OpenFile(maskFilePath, os.O_RDONLY, 0666)
	if err != nil {
		fmt.Println("open mask file: [mask"+ORG_ID+"] error:", err)
		return nil, err
	}

	maskStat, _ := maskFile.Stat()
	maskContent := make([]byte, maskStat.Size())
	readLen, err := maskFile.Read(maskContent)
	if err != nil || readLen != int(maskStat.Size()) {
		fmt.Println("read mask file: [mask"+ORG_ID+"] error:", err)
		return nil, err
	}
	return maskContent, nil
}
